package com.example.makerspace.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.makerspace.dao.DemandDAO;
import com.example.makerspace.dao.EnterpriseCertificationDAO;
import com.example.makerspace.dao.PersonalRecommendationsDAO;
import com.example.makerspace.dao.UserDAO;
import com.example.makerspace.domain.DemandDO;
import com.example.makerspace.domain.EnterpriseCertificationDO;
import com.example.makerspace.domain.PersonalRecommendationsDO;
import com.example.makerspace.domain.UserDO;
import com.example.makerspace.dto.PageRequest;
import com.example.makerspace.dto.Pagination;
import com.example.makerspace.dto.PersonalRecommendationsDTO;
import com.example.makerspace.dto.Result;
import com.example.makerspace.enums.ResultCodeEnum;
import com.example.makerspace.service.PersonalRecommendService;
import com.example.makerspace.utils.JwtUtils;
import com.example.makerspace.vo.ProductRecommendationVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PersonalRecommendServiceImpI implements PersonalRecommendService {

    public final static double PRAISE =  0.5;
    public final static Integer COLLECTION = 1;
    public final static double SHARE = 0.3;
    public final static double STAY = 0.1;
    public final static double IndustriesInterest = 0.1;
    public final static double ADDRESS = 0.3;

    @Resource
    private PersonalRecommendationsDAO personalRecommendationsDAO;

    @Resource
    private DemandDAO demandDAO;

    @Resource
    private UserDAO userDAO;


    @Resource
    private EnterpriseCertificationDAO enterpriseCertificationDAO;
    @Override
    public Result init(String username) {
        List<DemandDO> demandDOS = demandDAO.selectAll();
        for(int i=0;i<demandDOS.size();i++){
            PersonalRecommendationsDO personalRecommendationsDO1 = personalRecommendationsDAO.selectByProductId(username, demandDOS.get(i).getId());
            if(personalRecommendationsDO1!=null){
                continue;
            }
            synchronized (PersonalRecommendationsDO.class){
                double result=0;
                PersonalRecommendationsDO personalRecommendationsDO = new PersonalRecommendationsDO();
                personalRecommendationsDO.setStay(0);
                personalRecommendationsDO.setUsername(username);
                personalRecommendationsDO.setProductId(demandDOS.get(i).getId());
                UserDO userDO = userDAO.selectByUsername(username);
                if(userDO.getMapAddress()!=null){
                    if(userDO.getMapAddress().equals(demandDOS.get(0).getCompanyAddress())){
                        result=result+ADDRESS;
                    }
                }
                List<String> praiseUser =demandDOS.get(0).getPraiseUser();
                boolean contains = praiseUser.contains(username);
                if(contains){
                    result=result+PRAISE;
                }
                List<String> collectionUser = demandDOS.get(0).getCollectionUser();
                boolean contains1 = collectionUser.contains(username);
                if(contains1){
                    result=result+COLLECTION;
                }
                List<String> shareUser = demandDOS.get(0).getShareUser();
                boolean contains2 = shareUser.contains(username);
                if(contains2){
                    result=result+SHARE;
                }
                personalRecommendationsDO.setWeight(result);
                personalRecommendationsDO.setPerWeight(result);
                personalRecommendationsDAO.insert(personalRecommendationsDO);
            }
            }
        return  Result.success("用户个性化推荐初始化完成");
    }



    @Override
    public Result userStay(PersonalRecommendationsDTO personalRecommendationsDTO) {
        double result = 0;
        PersonalRecommendationsDO personalRecommendationsDO = personalRecommendationsDAO.selectByProductId(personalRecommendationsDTO.getUsername(), personalRecommendationsDTO.getProductId());
        int maxStay = Math.max(personalRecommendationsDTO.getStay(), personalRecommendationsDO.getStay());
            int difference = maxStay - personalRecommendationsDO.getStay();
            result = personalRecommendationsDO.getWeight() + (difference * STAY);
            personalRecommendationsDO.setStay(maxStay);
            personalRecommendationsDO.setPerWeight(result);
            personalRecommendationsDAO.updateById(personalRecommendationsDO);

        return Result.success("用户个性化推荐构建完成");
    }

    @Override
    public Result updatePersonalRecommend(PersonalRecommendationsDTO personalRecommendationsDTO) {
        double result=0;
        DemandDO demandDO = demandDAO.selectById(personalRecommendationsDTO.getProductId());
        PersonalRecommendationsDO personalRecommendationsDO = personalRecommendationsDAO.selectByProductId(personalRecommendationsDTO.getUsername(), personalRecommendationsDTO.getProductId());
        UserDO userDO = userDAO.selectByUsername(personalRecommendationsDTO.getUsername());
        if(userDO.getMapAddress()!=null){
            if(userDO.getMapAddress().equals(demandDO.getCompanyAddress())){
                result=result+ADDRESS;
            }
        }
        List<String> praiseUser =demandDO.getPraiseUser();
        boolean contains = praiseUser.contains(personalRecommendationsDTO.getUsername());
        if(contains){
            result=result+PRAISE;
        }
        List<String> collectionUser = demandDO.getCollectionUser();
        boolean contains1 = collectionUser.contains(personalRecommendationsDTO.getUsername());
        if(contains1){
            result=result+COLLECTION;
        }
        List<String> shareUser = demandDO.getShareUser();
        boolean contains2 = shareUser.contains(personalRecommendationsDTO.getUsername());
        if(contains2){
            result=result+SHARE;
        }
        personalRecommendationsDO.setPerWeight(result);
        personalRecommendationsDAO.updateById(personalRecommendationsDO);
        return Result.success("用户个性化推荐更新完成");
    }

    @Override
    public Result showProductBySort(PageRequest request) {
        IPage<DemandDO> demandDOIPage=new Page<>();
        String username = request.getUsername();

        Pagination pagination = request.getPagination();
        Map<String, Object> params = request.getParams();
        String demandName = MapUtils.getString(params, "demandName");
        String category = MapUtils.getString(params, "category");
        //根据浏览量排序
        String showNumber = MapUtils.getString(params, "showNumber");
        //根据点赞排序
        String praise = MapUtils.getString(params, "praise");
        //根据收藏排序
        String collection = MapUtils.getString(params, "collection");
        if(username.equals("")){
            if(demandName.equals("")&&showNumber.equals("")&&category.equals("")&&praise.equals("")&&category.equals("")){
                demandDOIPage = demandDAO.getDemandDOS(new Page<>(pagination.getPageNum(), pagination.getSize()));
                return Result.success(demandDOIPage);
            }
            demandDOIPage= demandDAO.getDemandDOSByCondition(new Page<>(pagination.getPageNum(), pagination.getSize()), demandName, category, showNumber, praise, collection);
            return Result.success(demandDOIPage);
        }else {
            if(demandName.equals("")&&showNumber.equals("")&&category.equals("")&&praise.equals("")&&category.equals("")){
                Page<ProductRecommendationVO> personRecommendSort = personalRecommendationsDAO.getPersonRecommendSort(new Page<>(pagination.getPageNum(), pagination.getSize()), username);
                return Result.success(personRecommendSort);
            }
            demandDOIPage= demandDAO.getDemandDOSByCondition(new Page<>(pagination.getPageNum(), pagination.getSize()), demandName, category, showNumber, praise, collection);
            return Result.success(demandDOIPage);
        }


    }


}
